program Scaner;
 uses crt,MyUnit;
 procedure Telo; forward;
 procedure BeginExe;
  var
   jj:byte;
  begin
   jj:=1;
   writeln(Fille,#9,'page 60,132');
   writeln(Fille,#9,'TITLE EndFil - результат работы компилятора');
   writeln(Fille,#9,'STSG    SEGMENT PARA STACK');
   writeln(Fille,#9,#9,'dw        128        dup(?)');
   writeln(Fille,#9,'STSG    ENDS');
   writeln(Fille,';----------------------------------------');
   writeln(Fille,#9,'DATASG  SEGMENT');

   writeln(Fille,#9,#9,'$Error',#9,'db',#9,#39,'Ошибка !!!',#39,','#39,'$',#39);
   writeln(Fille,#9,#9,'$ln',#9,'db',#9,'13,10',','#39,'$',#39);
   if Literal.FlagStackOpen then  {если есть литерал}
     with Literal do
      begin
       if StackDat^.link = nil then
         writeln(Fille,#9,#9,'$',jj,#9,'db',#9,StackDat^.Name,',',#39{'},'$',#39)
        else
        begin
         PointerStackDat:=StackDat;
         writeln(Fille,#9,#9,'$',jj,#9,'db',#9,StackDat^.Name,',',#39{'},'$',#39);
         while StackDat^.link <> nil do
          begin
           StackDat:=StackDat^.link;
           inc(jj);
           writeln(Fille,#9,#9,'$',jj,#9,'db',#9,StackDat^.Name,',',#39{'},'$',#39);
          end;
         StackDat:=PointerStackDat
        end;
      end;
   inc(jj);
   writeln(Fille,#9,#9,'$',jj,#9,'db',#9,'?');
   for jj:=1 to UkToT do
    begin
     with TablS[jj] do
     case Tip[1] of
      'C': writeln(Fille,#9,#9,name,#9,'db',#9,'?'); {char}
      'I': writeln(Fille,#9,#9,name,#9,'dw',#9,'?'); {integer}
      'B': case Tip[2] of
                'O': writeln(Fille,#9,#9,name,#9,'dw',#9,'?'); {boolean}
                'Y': writeln(Fille,#9,#9,name,#9,'db',#9,'?'); {byte}
           end;
      'W': writeln(Fille,#9,#9,name,#9,'dw',#9,'?');     {word}
      'S': writeln(Fille,#9,#9,name,#9,'db',#9,'256',#9,'dup(?)');
      '@': case TipLo[1] of
            'B','C': writeln(Fille,#9,#9,name,#9,'db',#9,Init,#9,'dup(0)');
            'I': writeln(Fille,#9,#9,name,#9,'dw',#9,Init,#9,'dup(0)');
            'S': writeln(Fille,#9,#9,name,#9,'db',#9,Init,#9,'dup ( ',
             Razm,' dup(0) )');

           end;
     end;
    end;
   writeln(Fille,#9,#9,'@@SchPu dw     0');     {word}
   writeln(Fille,#9,'DATASG  ENDS');
   writeln(Fille,';----------------------------------------');
   writeln(Fille,#9,'CODESG  SEGMENT');
   writeln(Fille,#9,'MAIN    PROC      FAR');
   writeln(Fille,#9,#9,'ASSUME    CS:CODESG,DS:DATASG,SS:STSG');
   writeln(Fille);
   writeln(Fille,#9,#9,'push    ds          ;сохраняем вход PSP');
   writeln(Fille,#9,#9,'mov     ax,0');
   writeln(Fille,#9,#9,'push    ax');
   writeln(Fille,#9,#9,'mov     ax,DATASG');
   writeln(Fille,#9,#9,'mov     ds,ax       ;установка сегмента данных');
   writeln(Fille,#9,#9,'mov     es,ax       ;установка сегмента данных');
   writeln(Fille);
   writeln(Fille,#9,#9,'push    ax');
   writeln(Fille,#9,#9,'push    bx');
   writeln(Fille,#9,#9,'push    cx');
   writeln(Fille,#9,#9,'push    dx');
   writeln(Fille,#9,#9,'push    di');
   writeln(Fille,#9,#9,'push    si');
   writeln(Fille,#9,#9,'push    bp');
   writeln(Fille,#9,#9,'push    sp');

  end;
  procedure EndExe;
   begin
    writeln(Fille,#9,#9,'mov    ax,0h');
    writeln(Fille,'endo:');
    writeln(Fille,#9,#9,'cmp    ax,0h');
    writeln(Fille,#9,#9,'je     endo1');

    writeln(Fille,#9,#9,'mov     cx,@@SchPu');
    writeln(Fille,'EnCik:');
    writeln(Fille,#9,#9,'pop     bx');
    writeln(Fille,#9,#9,'loop    EnCik');
    writeln(Fille,#9,#9'mov     ah,09');
    writeln(Fille,#9,#9'lea     dx,$ln');
    writeln(Fille,#9,#9'int     21h');

    writeln(Fille,#9,#9'mov     ah,09');
    writeln(Fille,#9,#9'lea     dx,$Error');
    writeln(Fille,#9,#9'int     21h');
    writeln(Fille,'endo1:');
    writeln(Fille);
    writeln(Fille,#9,#9,'pop    sp');
    writeln(Fille,#9,#9,'pop    bp');
    writeln(Fille,#9,#9,'pop    si');
    writeln(Fille,#9,#9,'pop    di');
    writeln(Fille,#9,#9,'pop    dx');
    writeln(Fille,#9,#9,'pop    cx');
    writeln(Fille,#9,#9,'pop    bx');
    writeln(Fille,#9,#9,'pop    ax');
    writeln(Fille);
    writeln(Fille,#9,#9,'RET');
    writeln(Fille,#9,'MAIN    ENDP');
    if DoCallDel then GenerDel;
    if DoCallCopy then GenerCopy;
    if DoCallIns then GenerIns;
    if DoCallClear then GenerClear;
    if DoCallPress then GenerPress;
    writeln(Fille,#9,'CODESG  ENDS');
    writeln(Fille,#9,#9,'END  MAIN');
   end;
{----------------------------------------------------------}

  procedure E;forward;
  procedure t;forward;
  procedure f;forward;
  procedure Z;
   begin
    E;
      if stro[1]<>'R'then Errora(4);
      if (stro<>'R12') then Errora(3);
   end;
  procedure E;
   begin
    T;
    while ((stro='R6'){+}or(stro='R7'){-}) do
     begin
      if stro='R6'{+} then
       begin
        Rezak(Ukaz,stro,ReadNot,Fil);
        writeln(Fille,#9,#9'push     ax      ; встретили э+э - сохраняем ах');
        writeln(Fille,#9,#9,'add      [@@SchPu],1');
        T;
        writeln(Fille,#9,#9'pop      bx');
        writeln(Fille,#9,#9,'sub      [@@SchPu],1');
        writeln(Fille,#9,#9'add      ax,bx');
       end
      else
      if stro='R7'{-} then
       begin
        Rezak(Ukaz,stro,ReadNot,Fil);
        writeln(Fille,#9,#9'push     ax');
        writeln(Fille,#9,#9,'add      [@@SchPu],1');
        T;
        writeln(Fille,#9,#9'pop      bx');
        writeln(Fille,#9,#9,'sub      [@@SchPu],1');
        writeln(Fille,#9,#9'sub      bx,ax');
        writeln(Fille,#9,#9'mov      ax,bx');
       end;
     end;
   end;
  procedure T;
   var
    VozvrOst:boolean;
   begin
    F;
    while ((stro='R4'){*}or(stro='R5'){/}) {and(length(X)<>0)} do
     begin
      if stro='R4'{*} then
       begin
        Rezak(Ukaz,stro,ReadNot,Fil);
        writeln(Fille,#9,#9'push     ax');
        writeln(Fille,#9,#9,'add      [@@SchPu],1');
        F;
        writeln(Fille,#9,#9'pop      bx');
        writeln(Fille,#9,#9,'sub      [@@SchPu],1');
        writeln(Fille,#9,#9'mul      bx');
       end
      else
      if stro='R5'{/} then
       begin
        VozvrOst:=false;
        Rezak(Ukaz,stro,ReadNot,Fil);
        if stro='R5' then  {если у нас i:=per//5 то возвр остаток от деления}
         begin
          VozvrOst:=true;
          Rezak(Ukaz,stro,ReadNot,Fil);
         end;
        writeln(Fille,#9,#9'push     ax      ; деление - сохраняем ах');
        writeln(Fille,#9,#9,'add      [@@SchPu],1');
        F;
        writeln(Fille,#9,#9'pop      bx');
        writeln(Fille,#9,#9,'sub      [@@SchPu],1');
        writeln(Fille,#9,#9'mov      dx,ax   ; меняем  ');
        writeln(Fille,#9,#9'mov      ax,bx   ; ах и bx ');
        writeln(Fille,#9,#9'mov      bx,dx   ; местами ');
        writeln(Fille,#9,#9'mov      dx,0');
        writeln(Fille,#9,#9'cmp      bx,0    ;проверка деления на 0');
        inc(MetDel);
        writeln(Fille,#9,#9'jne      noterr',MetDel);
        writeln(Fille,#9,#9'jmp      endo');

        writeln(Fille,'noterr',MetDel,':');
        writeln(Fille,#9,#9'div      bx');
        if VozvrOst then
         writeln(Fille,#9,#9'mov      ax,dx  ;возвращ остаток');
       end;
     end;
   end;
  procedure F;
   var
    sch,sch1,cod:integer;
    Helpstro,HlpStrLen,HlpStrM:string;
    Invert,FlagLocObrLength,FlagLocObrE:boolean;
    MetkaF1,MetkaF2:integer;
    VozvrLoc:boolean;
    HP:string;
   begin
    inc(MetkaF,3);
    MetkaF1:=MetkaF+1;
    MetkaF2:=MetkaF+2;
    Invert:=false;
    FlagLocObrLength:=FlagObrLength;
    FlagObrLength:=false;
    FlagLocObrE:=FlagObrE;
    VozvrLoc:=Vozvr;
    if stro='R7'{-} then
     begin
      Invert:=true;
      Rezak(Ukaz,stro,ReadNot,Fil);
     end;

    if stro[1]='H' then
     begin
      delete(stro,1,1);
      val(stro,sch,cod);
      Chisla.SearcElem(sch,Helpstro);{в Helpstr содерж-ся число под номером sch}
      writeln(Fille,#9,#9'mov      ax,',Helpstro,'     ;заносим в ах число');
      Rezak(Ukaz,stro,ReadNot,Fil); {когда встретили I:=, то перешли сюда}
      if Invert then writeln(Fille,#9,#9'neg      ax')
     end
    else
    {------------------------}
    begin
     if stro='R10'{(} then
      begin
       Rezak(Ukaz,stro,ReadNot,Fil);

            FlagObrE:=true;
            E;{в ах - смещение}
            FlagObrE:=false;

       if stro='R11'{)} then  Rezak(Ukaz,stro,ReadNot,Fil)
        else Errora(19);
      end
    else
    if stro[1]='I' then
     begin
      delete(stro,1,1);
      val(stro,sch,cod);
      ID.SearcElem(sch,Helpstro);{в Helpstr содерж-ся имя под номером sch}
      HP:=Helpstro; {запоминаем для типа char, если потреб-ся возвр знач-е}
      if TablS[sch-1].Tip ='@@arr@@' then
       begin
        Rezak(Ukaz,stro,ReadNot,Fil);
        if (stro<>'R15'){[} then Errora(35);
        if (stro='R15'){[} then
         begin
          Rezak(Ukaz,stro,ReadNot,Fil);
          HlpStrM:=stro;
          delete(HlpStrM,1,1);
          val(HlpStrM,sch1,cod);
          if stro[1]='I' then
          if (TablS[sch1-1].Tip='STRING') or (TablS[sch1-1].TipLo='STRING')or
           (TablS[sch1-1].Tip='CHAR') or (TablS[sch1-1].TipLo='CHAR') then
           Errora(38);

          if (stro[1] ='I')or (stro[1] ='H') or((stro[1] ='S'))
          then
           begin
            inc(KolRekurs);
            FlagObrE:=true;
            vozvr:=true;
            E;{в ах - смещение}
            vozvr:=false;
            FlagObrE:=false;
            dec(KolRekurs);

           end;


          if TablS[sch-1].TipLo ='INTEGER' then
           begin
            writeln(Fille,#9,#9'mov      bx,2     ;заносим в bх размер типа');
            writeln(Fille,#9,#9'mul      bx       ;получаем в ах смещение');
            writeln(Fille,#9,#9'sub      ax,2     ;т к начинается с 0');
           end
           else
           if (TablS[sch-1].TipLo ='BYTE')or(TablS[sch-1].TipLo ='CHAR')then
            begin
             writeln(Fille,#9,#9'sub      ax,1     ;т к начинается с 0');
            end
           else
           if TablS[sch-1].TipLo ='STRING' then
            begin
             writeln(Fille,#9,#9'mov      bx,256   ;заносим в bх размер типа');
             writeln(Fille,#9,#9'mul      bx       ;получаем в ах смещение');
             writeln(Fille,#9,#9'sub      ax,256   ;т к начинается с 0');
            end;

          writeln(Fille,#9,#9'mov      si,ax     ;заносим в si смещение');
         if (TablS[sch-1].TipLo='CHAR')and (vozvrLoc)and (IIFF) then
          {если нах-ся в "E S E" в if то IIFF=true}

          begin
           writeln(Fille,#9,#9'lea      bx,',HP,'  ;находимся в if  ');
           writeln(Fille,#9,#9'add      si,bx      ;сравниваем типы char ');
           writeln(Fille,#9,#9'xor      ax,ax      ;');
           writeln(Fille,#9,#9'mov      al,[si]    ;возвращ-м значение');
          end;



         end;{if [}
        if (stro<>'R16'){]} then Errora(36);
        if stro='R16' then Rezak(Ukaz,stro,ReadNot,Fil);
       end {if @@arr@@}
{--------------------------------------------------------------------}
       else
{--------------------------------------------------------------------}
    {простые идентиф-ры}
       begin
{----------------------------------------------------------------------}
      {ошибки}
        if (Tipi='@@arr@@')and (KolRekurs=0) then
         begin
          if TipiLo='BYTE' then
           if (TablS[sch-1].Tip<>'BYTE') then Errora(34);
          if TipiLo='INTEGER' then
           if (TablS[sch-1].Tip='CHAR') then Errora(34);
          if TipiLo='CHAR' then
           if (TablS[sch-1].Tip<>'CHAR') then Errora(34);
         end;
        if (Tipi='INTEGER')and (KolRekurs=0) then
         if (TablS[sch-1].Tip<>'BYTE') and (TablS[sch-1].Tip<>'INTEGER')
         and (TablS[sch-1].Tip<>'@@arr@@') then Errora(34);

        if (Tipi='BYTE') and (KolRekurs=0) then
         if (TablS[sch-1].Tip<>'BYTE') then Errora(34);

        if (KolRekurs<>0) and not FlagLocObrLength then
         if (TablS[sch-1].Tip='CHAR')or (TablS[sch-1].Tip='STRING')
         then Errora(34);


{----- конец ошибок -------------------------------------------------------------}

        if TablS[sch-1].Tip='INTEGER' then
        writeln(Fille,#9,#9'mov      ax,',Helpstro,'     ;заносим в ах идентиф-р или смещение')
        else
        if TablS[sch-1].Tip='BYTE' then
         begin
          writeln(Fille,#9,#9'xor      ax,ax');
          writeln(Fille,#9,#9'mov      al, ',Helpstro,'     ;заносим в аl идентиф-р или смещение');
          if (Tipi='INTEGER') or ((Tipi='@@arr@@')and(TipiLo='INTEGER'))
         and (vozvrLoc) then
           begin        {расш до intgr}
            writeln(Fille,#9,#9'cmp      al,0');
            writeln(Fille,#9,#9'jge       @Bz',Metkaf2,';     >0');
            writeln(Fille,#9,#9'mov      ah,0ffh');
            writeln(Fille,'@Bz',Metkaf2,': ');
           end
         end
        else
        if (TablS[sch-1].Tip='CHAR')and (vozvrLoc) then
         begin
          writeln(Fille,#9,#9'xor      ax,ax');
          writeln(Fille,#9,#9'mov      al, ',Helpstro,'     ;заносим в аl идентиф-р или смещение');
         end;


        if TablS[sch-1].Tip='STRING' then
          writeln(Fille,#9,#9'lea      si,',Helpstro);

        Rezak(Ukaz,stro,ReadNot,Fil);
       end;        {if}

{-------------------------------------------------------------------------}
{если обрабатываемый тип - массив, то в случае pp:=-A[1] инверсия производится}
{ в следующем ниже блоке (присутствует возврат как положительного, так и
  отриц значений)}

       if  FlagLocObrE and not FlagLocObrLength {and (KolRekurs<>0)}
        then  {когда for , if }
         begin
         if (TablS[sch-1].Tip='CHAR')or (TablS[sch-1].Tip='STRING')
         then Errora(34);
         if ((TablS[sch-1].Tip='@@arr@@') and (TablS[sch-1].TipLo='STRING'))or
       ((TablS[sch-1].Tip='@@arr@@') and (TablS[sch-1].TipLo='CHAR'))
         then Errora(34);
         end;

      if (TablS[sch-1].Tip='@@arr@@') then
                 {в si имееем смещение}
       begin
        if TablS[sch-1].TipLo='INTEGER' then
         begin
          writeln(Fille,#9,#9'lea      bx,',helpstro,'      ;массив');
          writeln(Fille,#9,#9'mov      ax,[bx+si]       ;возвращ значение');
          if (Tipi ='BYTE') or((Tipi ='@@arr@@')and(TipiLo ='BYTE'))
          then if KolRekurs=0 then Errora(34);
          if (Tipi ='CHAR') or((Tipi ='@@arr@@')and(TipiLo ='CHAR'))
          then  if KolRekurs=0 then Errora(34);
          if (Tipi ='STRING') or((Tipi ='@@arr@@')and(TipiLo ='STRING'))
          then  if KolRekurs=0 then Errora(34);

          if Invert then writeln(Fille,#9,#9'neg      ax')
         end;

        if TablS[sch-1].TipLo='BYTE' then
         begin
          if VozvrLoc then
           begin
            writeln(Fille,#9,#9'mov      ax,0');
            writeln(Fille,#9,#9'lea      bx,',helpstro,'      ;массив');
            writeln(Fille,#9,#9'mov      al,byte ptr [bx+si]       ;возвращ значение');
           end;
          if (Tipi ='CHAR') or((Tipi ='@@arr@@')and(TipiLo ='CHAR'))
          then  Errora(34);
          if (Tipi ='STRING') or((Tipi ='@@arr@@')and(TipiLo ='STRING'))
          then  Errora(34);

          if ((Tipi='INTEGER') or ((Tipi='@@arr@@')and(TipiLo='INTEGER')))
           and (vozvrLoc) then
           begin

            writeln(Fille,#9,#9'cmp      al,0');
            writeln(Fille,#9,#9'jge       @Bz',Metkaf2);
            writeln(Fille,#9,#9'mov      ah,0ffh');
            writeln(Fille,'@Bz',Metkaf2,': ');
           end;
          if Invert then
           if (Tipi ='INTEGER') or((Tipi ='@@arr@@')and(TipiLo ='INTEGER'))
           then writeln(Fille,#9,#9'neg      ax')
          else
          writeln(Fille,#9,#9'neg      al');

         end; {if TipLo = BYTE}
        if TablS[sch-1].TipLo='CHAR' then
         begin
          if (Tipi ='INTEGER') or((Tipi ='@@arr@@')and(TipiLo ='INTEGER'))
           then Errora(34);
          if (Tipi ='BYTE') or((Tipi ='@@arr@@')and(TipiLo ='BYTE'))
           then Errora(34);
         end;

        if (TablS[sch-1].TipLo='STRING')and(not FlagLocObrLength) then
         begin
          if (Tipi ='INTEGER') or((Tipi ='@@arr@@')and(TipiLo ='INTEGER'))
           then Errora(34);
          if (Tipi ='BYTE') or((Tipi ='@@arr@@')and(TipiLo ='BYTE'))
           then Errora(34);
         end;
       end{if @@arr@@}
{-------------------------------------------------------------------}


     end{ if stro[1]='I'}
     else
    if stro[1]='S' then
     begin
      FlagObrLength:=true;
      delete(stro,1,1);
      val(stro,sch,cod);
      if sch<>14 then Errora(20);
      if (Tipi = 'INTEGER') or (TipiLo='INTEGER') or (Tipi='') or
      (Tipi = 'BYTE') or (TipiLo='BYTE') then
       begin
        Rezak(Ukaz,stro,ReadNot,Fil); {вырезаем "("}
        if stro<>'R10'{(} then Errora(32);
        Rezak(Ukaz,stro,ReadNot,Fil);
        if (stro[1]<>'I') then Errora(8);
        HlpStrLen:=stro;
        delete(HlpStrLen,1,1);
        val(HlpStrLen,sch1,cod);
        if (TablS[sch1-1].Tip='INTEGER') or (TablS[sch1-1].TipLo='INTEGER')or
        (TablS[sch1-1].Tip='BYTE') or (TablS[sch1-1].TipLo='BYTE') then
         Errora(39);
        ID.SearcElem(sch1,HlpStrLen);
        if (TablS[sch1-1].Tip='@@arr@@') then
         begin
          inc(KolRekursF);
          F;
          dec(KolRekursF);
         end;
        {после в si имеем смещение}
        writeln(Fille,#9,#9'mov      ax,0');
        writeln(Fille,#9,#9'lea      bx,',HlpStrLen,'      ;массив');

        {в ax имеем значение}
        if (TablS[sch1-1].Tip='@@arr@@') then
          writeln(Fille,#9,#9'mov      al,byte ptr [bx+si]       ;это LENGTH')
         else
        if (TablS[sch1-1].Tip='STRING')then
          writeln(Fille,#9,#9'mov      al,byte ptr [bx]       ;это LENGTH');
        if TablS[sch1-1].Tip='STRING' then Rezak(Ukaz,stro,ReadNot,Fil); {вырезаем ")"}
        if (stro<>'R11'){)}then Errora(33);
       end;
      FlagObrLength:=false;
      Rezak(Ukaz,stro,ReadNot,Fil);
     end
    else Errora(19);
{-------------------------------------------------------------------}
{ если обраб-мый тип не массив то выполняются следующие действия:}
{ pp:=i, A[i]:=kk    }
   if (TablS[sch-1].Tip<>'@@arr@@') then
     if Invert and ((Tipi='INTEGER') or ((Tipi='INTEGER')and
     (TablS[sch-1].Tip='BYTE'))) then
      writeln(Fille,#9,#9'neg      ax')
      else
     if Invert and (Tipi='BYTE') then
      writeln(Fille,#9,#9'neg      al')
      else
     if Invert and (Tipi='@@arr@@') then
      begin
       if TipiLo='BYTE' then writeln(Fille,#9,#9'neg      al');
       if (TipiLo='INTEGER') or ((TipiLo='INTEGER') and
          (TablS[sch-1].Tip='BYTE')) then
          writeln(Fille,#9,#9'neg      ax');
      end;
    end;{if не число}
{-----------------------------------------------------------------------}
   end;
 procedure Prisvaivanie_Char;
  var
   Sem_Info,Sem_Info1:integer;
   cod,cod1:integer;
   HelpStro,HelpStro1:string;
   FlagIndex:boolean;
  begin
{--------------------------------------------------------------------}
   {формат записи строки :  1-й байт - длина строки (вместе со знаком $),}
   {далее идет сама строка, последний байт - $}
   FlagIndex:=false;
   Tipi:='';
   TipiLo:='';
   Helpstro:=stro;
   delete(helpstro,1,1);                              {КУДА}
   val(helpstro,Sem_Info,cod);
   writeln(Fille,';------ начало присваивания ------------');
   if Sem_Info = 1  then Errora(16);
   ID.SearcElem(Sem_Info,Helpstro);{имя куда будем пересылать}
    if TablS[Sem_info-1].Tip='@@arr@@' then
     begin
      if (stro[1] ='I')or (stro[1] ='H') then F;{возвращает смещение в si}
      writeln(Fille,#9,#9'push     si');
      writeln(Fille,#9,#9,'add      [@@SchPu],1');
     end                                        {значение в ах}
     else
    Rezak(Ukaz,stro,ReadNot,Fil);
{----------------------------------------------------------------------}

   if stro[1]<>'R' then Errora(4);
   if stro<>'R13'{:} then Errora(18);

   Rezak(Ukaz,stro,ReadNot,Fil);
   if stro[1]<>'R' then Errora(4);
   if stro<>'R3'{=} then Errora(18);
   Rezak(Ukaz,stro,ReadNot,Fil);
   if (stro[1]<>'I') and(stro[1]<>'L') then Errora(31);
{----------------------------------------------------------------------}
   Tipi:=TablS[Sem_info-1].Tip;
   TipiLo:=TablS[Sem_info-1].TipLo;
   Helpstro1:=stro;
   delete(helpstro1,1,1);                     {ОТКУДА}
   val(helpstro1,Sem_Info1,cod);

   if stro[1]='I' then
    begin
     ID.SearcElem(Sem_Info1,Helpstro1); {имя, откуда будем пересылать}
     if (Sem_Info1 = 1) and(stro[1]='I') then Errora(16);
     if TablS[Sem_info1-1].Tip='@@arr@@' then
      begin
       if (stro[1] ='I')or (stro[1] ='H') then F;{возвращает смещение в si}
     {смещение переменной имеем в si, но это - откуда}

      end;
    end;
   if stro[1]<>'L' then
   if ((TablS[Sem_info1-1].Tip ='@@arr@@')and(TablS[Sem_info1-1].TipLo ='STRING'))
    or (TablS[Sem_info1-1].Tip ='STRING') then
    begin
     if (TablS[Sem_info1-1].Tip ='STRING')then Rezak(Ukaz,stro,ReadNot,Fil);
     if stro='R15' then
      begin
      writeln(Fille,#9,#9'push     si');
      writeln(Fille,#9,#9,'add      [@@SchPu],1');
      FlagIndex:=true;
      Rezak(Ukaz,stro,ReadNot,Fil);
      E;
      {в ax - индекс}
      if stro<>'R16' then Errora(36);
      Rezak(Ukaz,stro,ReadNot,Fil);
     end;
    end;


{-----------------------------------------------------------------------}
   {если массив}

   with TablS[Sem_info-1] do
   if Tip ='@@arr@@' then
    {в di - смещение - куда, в si - откуда}
    begin
{-------------------------------------------------------------}
     if  FlagIndex then
      begin
       writeln(Fille,#9,#9'pop      si');
       writeln(Fille,#9,#9,'sub      [@@SchPu],1');
      end; {FlagIndex}
{-------------------------------------------------------------}
     writeln(Fille,#9,#9'pop      di');
     writeln(Fille,#9,#9,'sub      [@@SchPu],1');
     writeln(Fille,#9,#9'lea      bx,',helpstro); {загружаем куда}
     writeln(Fille,#9,#9'add      di,bx     ;смещение +ем'); {загружаем куда}
{--------------------------------------------------------------}
     if TipLo = 'CHAR' then {если у нас что-то вроде A[1]:=....}
      begin
       if (TablS[Sem_info1-1].Tip='CHAR') and (stro[1]<>'L') then
        begin
         writeln(Fille,#9,#9'mov      al,',Helpstro1);
         writeln(Fille,#9,#9'mov      [di],al');
         Rezak(Ukaz,stro,ReadNot,Fil);
        end;

          if (stro[1]<>'L') then
           begin
            if (TablS[Sem_info1-1].TipLo ='CHAR') then
              begin
               writeln(Fille,#9,#9'mov      bp,si');
               writeln(Fille,#9,#9'lea      si,',helpstro1); {загружаем откуда}
               writeln(Fille,#9,#9'add      si,bp     ;смещение +ем');
               writeln(Fille,#9,#9'mov      al,byte ptr [si]');
               writeln(Fille,#9,#9'mov      [di],al'); {куда}
              end
           end
           else
           if (stro[1]='L') then
             begin
              if length(HelpStro1)>3 then Errora(34);
              writeln(Fille,#9,#9'mov     al,$',Helpstro1);
              writeln(Fille,#9,#9'mov     [di],al');
              Rezak(Ukaz,stro,ReadNot,Fil);
             end;



       if ((TablS[Sem_info1-1].TipLo='STRING')or
        (TablS[Sem_info1-1].Tip='STRING')) and FlagIndex then
         begin
          if TablS[Sem_info1-1].Tip='STRING' then
            begin
             writeln(Fille,#9,#9'lea     si,',Helpstro1);{откуда}
             writeln(Fille,#9,#9'add     si,ax');{откуда}
            end
            else
            begin
             writeln(Fille,#9,#9'mov      bp,si');
             writeln(Fille,#9,#9'lea      si,',helpstro1); {загружаем откуда}
             writeln(Fille,#9,#9'add      si,bp     ;смещение +ем');
             if FlagIndex then
              writeln(Fille,#9,#9'add      si,ax     ;смещение +ем');
            end;
            writeln(Fille,#9,#9'mov      al,byte ptr [si]');
            writeln(Fille,#9,#9'mov      [di],al');
          end;
      end {if char}
{--------------------------------------------------------------}
      else
{-----------------------------------------}
      begin
       if (stro[1]<>'L')then
       begin
        if (TipLo='STRING')and ((TablS[Sem_info1-1].Tip='STRING')
        or ((TablS[Sem_info1-1].Tip='@@arr@@')and
        (TablS[Sem_info1-1].TipLo='STRING'))) then
         begin
          writeln(Fille,';------  пересылка строки из одной переменной в другую-------');
          writeln(Fille,#9,#9'push    cx');
          writeln(Fille,#9,#9,'add      [@@SchPu],1');
          if (TipLo='STRING')and (TablS[Sem_info1-1].Tip='STRING') then
           begin
            writeln(Fille,#9,#9'lea     si,',Helpstro1);
            if FlagIndex then
             begin
              writeln(Fille,#9,#9'mov     bx,si');
              writeln(Fille,#9,#9'add     si,ax      ;+ смещение внутри строки');
             end
           end
           else
           begin
            writeln(Fille,#9,#9'lea     bx,',Helpstro1);
            writeln(Fille,#9,#9'add     si,bx');
            if FlagIndex then
              writeln(Fille,#9,#9'add     si,ax      ;+ смещение внутри строки');

           end;
          writeln(Fille,#9,#9'mov     cx,0');
          if not FlagIndex then
           begin
            writeln(Fille,#9,#9'mov     cl,[si]   ;размер строки');
            writeln(Fille,#9,#9'add     cx,1      ;т к байт размера тоже передаем');
           end
           else
           begin
            writeln(Fille,#9,#9'mov     cl,1   ;один символ');
            writeln(Fille,#9,#9'mov     [di],cx      ;записываем размер строки');
            writeln(Fille,#9,#9'inc     di');
           end;
          writeln(Fille,#9,#9'rep     movsb');
          writeln(Fille,#9,#9'mov     [di],byte ptr ',#39,'$',#39);
          writeln(Fille,#9,#9'pop     cx');
          writeln(Fille,#9,#9,'sub      [@@SchPu],1');
          writeln(Fille,';------  конец пересылки-------');
         end;

        if (TipLo='STRING')and ((TablS[Sem_info1-1].Tip='CHAR')
        or ((TablS[Sem_info1-1].Tip='@@arr@@')and
        (TablS[Sem_info1-1].TipLo='CHAR'))) then
         begin
          writeln(Fille,';------  пересылка символа в строку -------');
          writeln(Fille,#9,#9'push    cx');
          writeln(Fille,#9,#9,'add      [@@SchPu],1');
          if (TipLo='STRING')and (TablS[Sem_info1-1].Tip='CHAR') then
           begin
            {di уже инициализирован}
            writeln(Fille,#9,#9'mov     al,',Helpstro1);
            Rezak(Ukaz,stro,ReadNot,Fil);
           end
           else
           begin
            writeln(Fille,#9,#9'lea     bx,',Helpstro1);
            writeln(Fille,#9,#9'add     si,bx');
           end;
          writeln(Fille,#9,#9'mov     cx,1');
          writeln(Fille,#9,#9'mov     [di],cx      ;записываем размер строки');
          writeln(Fille,#9,#9'inc     di');
          if (TablS[Sem_info1-1].Tip='@@arr@@') then
           writeln(Fille,#9,#9'mov     al,byte ptr [si]');

          writeln(Fille,#9,#9'mov     [di],al');
          writeln(Fille,#9,#9'inc     di');
          writeln(Fille,#9,#9'mov     [di],byte ptr ',#39,'$',#39);
          writeln(Fille,#9,#9'pop     cx');
          writeln(Fille,#9,#9,'sub      [@@SchPu],1');
          writeln(Fille,';------  конец пересылки-------');

         end;
        end;{<>'L'}
        if stro[1]='L' then
         begin
          writeln(Fille,';------  пересылка литерала в строку-------');
          writeln(Fille,#9,#9'push    cx');
          writeln(Fille,#9,#9,'add      [@@SchPu],1');
          writeln(Fille,#9,#9'lea     si,$',Sem_info1); {откуда}
          writeln(Fille,#9,#9'lea     bx,$',Sem_info1+1);
          writeln(Fille,#9,#9'sub     bx,si     ;в bx размер литерала');
          writeln(Fille,#9,#9'sub     bx,1      ;т к литерал оканч-ся на $');
          writeln(Fille,#9,#9'mov     cx,bx');
          writeln(Fille,#9,#9'mov     [di],cx      ;записываем размер строки');
          writeln(Fille,#9,#9'inc     di');
          writeln(Fille,#9,#9'rep     movsb');
          writeln(Fille,#9,#9'mov     [di],byte ptr ',#39,'$',#39);
          writeln(Fille,#9,#9,'sub      [@@SchPu],1');
          writeln(Fille,#9,#9'pop     cx');
          writeln(Fille,';------  конец пересылки литерала в строку-------');
          Rezak(Ukaz,stro,ReadNot,Fil);
         end; {='L'}
      end; {if not char}
    end {if Tip='@@arr@@'}
     else
    begin
{------------------------------------------------------------------------}
    {если простые идентификаторы}
     if  FlagIndex then
       begin
        writeln(Fille,#9,#9'pop      si');
        writeln(Fille,#9,#9,'sub      [@@SchPu],1');
       end;
     if (TablS[Sem_info-1].Tip ='CHAR') then
       begin

        if TablS[Sem_info1-1].Tip ='CHAR' then
          begin
            writeln(Fille,#9,#9'mov',#9,'al,',Helpstro1);{откуда}
            writeln(Fille,#9,#9'mov',#9,Helpstro,',al'); {куда}
            Rezak(Ukaz,stro,ReadNot,Fil);
          end;
          if (stro[1]<>'L') then
           begin
            if (TablS[Sem_info1-1].TipLo ='CHAR') then
              begin
               writeln(Fille,#9,#9'mov      bp,si');
               writeln(Fille,#9,#9'lea      si,',helpstro1); {загружаем откуда}
               writeln(Fille,#9,#9'add      si,bp     ;смещение +ем');
               writeln(Fille,#9,#9'mov      al,byte ptr [si]');
               writeln(Fille,#9,#9'mov',#9,Helpstro,',al'); {куда}
              end
           end;
           if (stro[1]='L') then
             begin
              if length(HelpStro1)>3 then Errora(34);
              writeln(Fille,#9,#9'mov     al,$',Helpstro1);
              writeln(Fille,#9,#9'mov',#9,Helpstro,',al');
              Rezak(Ukaz,stro,ReadNot,Fil);
             end;
           if ((TablS[Sem_info1-1].TipLo='STRING')or
           (TablS[Sem_info1-1].Tip='STRING')) and FlagIndex then
             begin
               if TablS[Sem_info1-1].Tip='STRING' then
                 begin
                  writeln(Fille,#9,#9'lea     si,',Helpstro1);{откуда}
                  writeln(Fille,#9,#9'add     si,ax');{откуда}
                 end
                 else
                 begin
                  writeln(Fille,#9,#9'mov      bp,si');
                  writeln(Fille,#9,#9'lea      si,',helpstro1); {загружаем откуда}
                  writeln(Fille,#9,#9'add      si,bp     ;смещение +ем');
                  writeln(Fille,#9,#9'add     si,ax');
                 end;
               writeln(Fille,#9,#9'mov      al,byte ptr [si]');
               writeln(Fille,#9,#9'mov      ',HelpStro,',al');
             end
       end;  {if char}
{----------------------------------------------------------------------}
      if stro[1]<>'L' then
      begin
       if ((TablS[Sem_info-1].Tip='STRING')and(TablS[Sem_info1-1].Tip='STRING'))
       or ((TablS[Sem_info-1].Tip='STRING')and(TablS[Sem_info1-1].Tip='@@arr@@')
       and (TablS[Sem_info1-1].TipLo='STRING')) then
        begin
         writeln(Fille,';------  пересылка строки из одной переменной в другую-------');
         writeln(Fille,#9,#9'push    cx');
         writeln(Fille,#9,#9,'add      [@@SchPu],1');
         writeln(Fille,#9,#9'lea     di,',Helpstro); {куда}

         if TablS[Sem_info1-1].TipLo='STRING' then
          begin
           writeln(Fille,#9,#9'lea     bx,',Helpstro1);{откуда}
           writeln(Fille,#9,#9'add     si,bx      ;+ смещени внутри строки');
          end
          else
           writeln(Fille,#9,#9'lea     si,',Helpstro1);{откуда}

         if FlagIndex then
          writeln(Fille,#9,#9'add     si,ax       ;+ смещени внутри строки');

         writeln(Fille,#9,#9'mov     cx,0');
         if not FlagIndex then
          begin
           writeln(Fille,#9,#9'mov     cl,[si]   ;размер строки');
           writeln(Fille,#9,#9'add     cx,1      ;т к байт размера тоже передаем');
          end
          else
          begin
           writeln(Fille,#9,#9'mov     cl,1   ;размер строки');
           writeln(Fille,#9,#9'mov     [di],cx      ;записываем размер строки');
           writeln(Fille,#9,#9'inc     di');
          end;

         writeln(Fille,#9,#9'rep     movsb');
         writeln(Fille,#9,#9'mov     [di],byte ptr ',#39,'$',#39);
         writeln(Fille,#9,#9,'sub      [@@SchPu],1');
         writeln(Fille,#9,#9'pop     cx');
         writeln(Fille,';------  конец пересылки-------');
        end;



        if (Tip='STRING')and ((TablS[Sem_info1-1].Tip='CHAR')
        or ((TablS[Sem_info1-1].Tip='@@arr@@')and
        (TablS[Sem_info1-1].TipLo='CHAR'))) then
         begin
          writeln(Fille,';------  пересылка символа в строку -------');
          writeln(Fille,#9,#9'push    cx');
          writeln(Fille,#9,#9,'add      [@@SchPu],1');
          writeln(Fille,#9,#9'lea     di,',Helpstro); {куда}
          if (Tip='STRING')and (TablS[Sem_info1-1].Tip='CHAR') then
           begin
            {di уже инициализирован}
            writeln(Fille,#9,#9'mov     al,',Helpstro1);
            Rezak(Ukaz,stro,ReadNot,Fil);
           end
           else
           begin
            writeln(Fille,#9,#9'lea     bx,',Helpstro1);
            writeln(Fille,#9,#9'add     si,bx');
           end;
          writeln(Fille,#9,#9'mov     cx,1');
          writeln(Fille,#9,#9'mov     [di],cx      ;записываем размер строки');
          writeln(Fille,#9,#9'inc     di');
          if (TablS[Sem_info1-1].Tip='@@arr@@') then
           writeln(Fille,#9,#9'mov     al,byte ptr [si]');


          writeln(Fille,#9,#9'mov    [di],al');
          writeln(Fille,#9,#9'inc     di');
          writeln(Fille,#9,#9'mov     [di],byte ptr ',#39,'$',#39);
          writeln(Fille,#9,#9'pop     cx');
          writeln(Fille,#9,#9,'sub      [@@SchPu],1');
          writeln(Fille,';------  конец пересылки-------');
         end;
       end {<>'L'}
      else
      if stro[1]='L' then
       begin
        writeln(Fille,';------  пересылка литерала в строку-------');
        writeln(Fille,#9,#9'push    cx');
        writeln(Fille,#9,#9,'add      [@@SchPu],1');
        writeln(Fille,#9,#9'lea     si,$',Sem_info1); {откуда}
        writeln(Fille,#9,#9'lea     di,$',Sem_info1+1);
        writeln(Fille,#9,#9'sub     di,si     ;в di размер литерала'); {откуда}
        writeln(Fille,#9,#9'sub     di,1      ;т к $ не передаем');
        writeln(Fille,#9,#9'mov     cx,di');
        writeln(Fille,#9,#9'lea     di,',Helpstro);{куда}
        writeln(Fille,#9,#9'mov     [di],cl        ;первый бай - размер');
        writeln(Fille,#9,#9'inc     di             ;пишем со второго байта');
        writeln(Fille,#9,#9'rep     movsb');
        writeln(Fille,#9,#9'mov     [di],byte ptr ',#39,'$',#39);
        writeln(Fille,#9,#9,'sub      [@@SchPu],1');
        writeln(Fille,#9,#9'pop     cx');
        writeln(Fille,';------  конец пересылки литерала в строку-------');
        Rezak(Ukaz,stro,ReadNot,Fil);
       end;
    end;{простые идентиф-ры}
   if stro<>'R12'then Errora(26);
   Rezak(Ukaz,stro,ReadNot,Fil);{стоим на следующем элементе}
   writeln(Fille,';------  конец присваивания -------');
  end;
{---------------------------------------------------}
{---------------------------------------------------}
 procedure Prisvaivanie_Int_Byte;
  var
   Sem_Info:integer;
   cod:integer;
   Helpstro:string;
  begin
   Helpstro:=stro;
   delete(helpstro,1,1);
   val(helpstro,Sem_Info,cod);
   writeln(Fille,';------ начало присваивания ------------');
   Tipi:='';
   TipiLo:='';
   if Sem_Info = 1  then Errora(16);
   ID.SearcElem(Sem_Info,Helpstro);
    if TablS[Sem_info-1].Tip='@@arr@@' then
     begin
      if (stro[1] ='I')or (stro[1] ='H') then
      begin
       vozvr:=false;
       F;{возвращает смещение в si}
      end;
      writeln(Fille,#9,#9'push     si');
      writeln(Fille,#9,#9,'add      [@@SchPu],1');
     end                                        {значение в ах}
     else
   Rezak(Ukaz,stro,ReadNot,Fil);
   if stro<>'R13'{:} then Errora(18);
   Rezak(Ukaz,stro,ReadNot,Fil);
   if stro[1]<>'R' then Errora(4);
   if stro<>'R3'{=} then Errora(18);
   Tipi:=TablS[Sem_info-1].Tip;
   TipiLo:=TablS[Sem_info-1].TipLo;

   Rezak(Ukaz,stro,ReadNot,Fil);
   vozvr:=true;
   Z;
   {в ах результат}
   vozvr:=false;
   if TablS[Sem_info-1].Tip ='@@arr@@' then
    begin
     writeln(Fille,#9,#9'pop      si');
     writeln(Fille,#9,#9,'sub      [@@SchPu],1');
     writeln(Fille,#9,#9'lea      bx,',helpstro); {}
     if TablS[Sem_info-1].TipLo='INTEGER' then
     writeln(Fille,#9,#9'mov      [bx+si],ax');
     if TablS[Sem_info-1].TipLo='BYTE' then
     writeln(Fille,#9,#9'mov      byte ptr [bx+si],al');

    end
    else
     if TablS[Sem_info-1].Tip='INTEGER' then
     writeln(Fille,#9,#9'mov',#9,' ',Helpstro,',ax')
     else
     writeln(Fille,#9,#9'mov',#9,' ',Helpstro,',al');
   writeln(Fille,';------ конец присваивания ------------');
   Rezak(Ukaz,stro,ReadNot,Fil);
   {стоим на следующем после ";"}
  end;
 procedure Raspozn_IF;
  var
   Sem_Info,Sem_Info1:integer;
   info,sch,cod:integer;
   MetkaIf1,MetkaIf2,MetkaIf3:integer;
   HelpInfo:string;
  begin
   Sem_Info:=0;
   Sem_Info1:=0;
   inc(MetkaIf,4);
   MetkaIf1:=MetkaIf+1;
   MetkaIf2:=MetkaIf+2;
   MetkaIf3:=MetkaIf+3;
   Tipi:='';{т к нет присваивания}
   Rezak(Ukaz,stro,ReadNot,Fil);
   writeln(Fille,';--------------- if ',MetkaIf1,'----------------');
   if (stro[1]<>'H')and (stro[1]<>'I') and (stro[1]<>'S') then Errora(20);
   HelpInfo:=stro;
   delete(HelpInfo,1,1);
   val(HelpInfo,sch,cod);
   if (TablS[sch-1].Tip='CHAR')or((TablS[sch-1].TipLo='CHAR')) then
   vozvr:=true else vozvr:=false;
   IIFF:=true;
   E;
   writeln(Fille,#9,#9'push     ax');
   writeln(Fille,#9,#9,'add      [@@SchPu],1');
   if stro[1]<>'R' then Errora(4);
   delete(stro,1,1);
   val(stro,info,cod);
   if (info<= 3) and (info>=1) then Sem_Info:=info else Errora(3);
   Rezak(Ukaz,stro,ReadNot,Fil);
   if stro[1]='R' then
    begin
     delete(stro,1,1);
     val(stro,info,cod);
     if (info<= 3) and (info>=1) then Sem_Info1:=info else Errora(3);
     Rezak(Ukaz,stro,ReadNot,Fil);
    end;
   if (stro[1]<>'H')and (stro[1]<>'I') and (stro[1]<>'S') then Errora(20);
   vozvr:=false;
   HelpInfo:=stro;
   delete(HelpInfo,1,1);
   val(HelpInfo,sch,cod);
   if (TablS[sch-1].Tip='CHAR')or((TablS[sch-1].TipLo='CHAR')) then
   vozvr:=true else vozvr:=false;

   E;
   IIFF:=false;
   writeln(Fille,#9,#9'pop      bx');
   writeln(Fille,#9,#9,'sub      [@@SchPu],1');
    writeln(Fille,#9,#9'cmp      bx,ax');
   case  Razdel[Sem_Info] of
    '>': if Sem_Info1<>0 then
          begin
           if Razdel[Sem_Info1] = '=' then
            writeln(Fille,#9,#9'jge       @',MetkaIf3,'      ;переход по >=');
          end
          else
           writeln(Fille,#9,#9'jg       @',MetkaIf3,'      ;переход по >');
    '<': if Sem_Info1<>0 then
          begin
           if Razdel[Sem_Info1] = '=' then
            writeln(Fille,#9,#9'jle       @',MetkaIf3,'      ;переход по <=');
           if Razdel[Sem_Info1] = '>' then
            writeln(Fille,#9,#9'jne       @',MetkaIf3,'      ;переход по <>');
          end
          else
           writeln(Fille,#9,#9'jl       @',MetkaIf3,'      ;переход по <');
    '=': if Sem_Info1=0 then
          begin
           if Razdel[Sem_Info] = '=' then
            writeln(Fille,#9,#9'je      @',MetkaIf3,'      ;переход по =');
          end
          else Errora(3);
   end;
   {а теперь уже стоим на then}
   writeln(Fille,#9,#9'jmp      @',MetkaIf1);

   writeln(Fille,'@',MetkaIf3,':');
   if stro = 'S31'{then} then
    begin
     Rezak(Ukaz,stro,ReadNot,Fil);
     if (stro[1]<>'S')and (stro[1]<>'I') then Errora(22);
     if stro <> 'S24'{begin} then Errora(23);
     Rezak(Ukaz,stro,ReadNot,Fil);{сразу на после begin}
     if (stro[1]<>'S')and (stro[1]<>'I') then Errora(22);
     writeln(Fille,'; тело then ниже до @',MetkaIf1);
     while (stro<>'S25') and (stro <>'') do
      begin
       Telo; {тело  then  begin ...... end}
      end;
     {'',end,else}
     if stro='' then Errora(24);
{---------------------------------------------------}
     if (stro = 'S25'){end}then
      begin
       Rezak(Ukaz,stro,ReadNot,Fil);
       if stro[1] <>'R' then Errora(4);
       if stro <>'R12' then Errora(26);
      end
     else Errora(24);
{---------------------------------------------------}
     Rezak(Ukaz,stro,ReadNot,Fil);

{---------------------------------------------------}
     {начинаем генерировать тело после else}
     if stro = 'S32'{else} then
      begin
       writeln(Fille,#9,#9,'jmp      @',MetkaIf2,'           ;переход на после else');
       writeln(Fille,'@',MetkaIf1,':');
       writeln(Fille,'; тело else ниже до @',MetkaIf2);
       Rezak(Ukaz,stro,ReadNot,Fil);
       if (stro[1]<>'S')and (stro[1]<>'I') then Errora(22);
       if stro <> 'S24'{begin} then Errora(23);
       Rezak(Ukaz,stro,ReadNot,Fil);{сразу на после begin}
       if (stro[1]<>'S')and (stro[1]<>'I') then Errora(22);
       while (stro<>'S25') and (stro <>'') do
        begin
         Telo; {тело  then  begin ...... end}
        end;
       {'',end,else}

{---------------------------------------------------}
       if stro='' then Errora(24);
       if (stro = 'S25'){end}then
        begin
         Rezak(Ukaz,stro,ReadNot,Fil);
         if stro[1] <>'R' then Errora(4);
         if stro <>'R12' then Errora(26);
        end
        else Errora(24);
       writeln(Fille,'@',MetkaIf2,':');
       Rezak(Ukaz,stro,ReadNot,Fil);
      end {"else"} else writeln(Fille,'@',MetkaIf1,':');

    end else Errora(21);
   writeln(Fille,';--------------- end if ',MetkaIf1,' ----------------');
  end;
 procedure Raspozn_FOR;
  var
   Flag_To_DownTo:boolean;
   sch,cod:integer;
   Sem_Info:integer;
   MetkaFor1,MetkaFor2:integer;
   helpstro:string;
  begin
   {for i:=1 to do}

   inc(MetkaFor,2);
   MetkaFor1:=MetkaFor+1;
   MetkaFor2:=MetkaFor+2;
   writeln(Fille,';----------- for begin ',MetkaFor1,' ---------------');
      {сохраняем cx}
   Rezak(Ukaz,stro,ReadNot,Fil);   {читаем следующий после "for"}
   if stro[1]<>'I' then Errora(27);

   delete(stro,1,1);                         { сохраняем    }
   val(stro,Sem_Info,cod);                   { семантическую}
   if Sem_Info = 1  then Errora(16);         {              }

   Rezak(Ukaz,stro,ReadNot,Fil);
   if stro[1]<>'R' then Errora(4);
   if stro<>'R13'{:} then Errora(18);      { разделители}
   Rezak(Ukaz,stro,ReadNot,Fil);           {            }
   if stro[1]<>'R' then Errora(4);
   if stro<>'R3'{=} then Errora(18);
   Rezak(Ukaz,stro,ReadNot,Fil);
   if (stro[1]='R') then Errora(22);
   vozvr:=true;
   E;

   ID.SearcElem(Sem_Info,Helpstro);
   if TablS[Sem_Info-1].Tip='INTEGER' then
   writeln(Fille,#9,#9'mov',#9,' ',Helpstro,',ax') {имя переменной цикла}
   else
   writeln(Fille,#9,#9'mov',#9,' ',Helpstro,',al') {имя переменной цикла};
   {стоим на следующем после "E"}
   writeln(Fille,#9,#9'push     ax      ;помещаем в стек начальн. зн-е перем цикла');
   writeln(Fille,#9,#9,'add      [@@SchPu],1');
   if (stro<>'S27'){to}and (stro<>'S28'){downto}then Errora(28);
   if (stro='S27'){to}then  Flag_To_DownTo:=true;
   if (stro='S28'){downto}then  Flag_To_DownTo:=false;
   Rezak(Ukaz,stro,ReadNot,Fil);
   if (stro[1]<>'H') and (stro[1]<>'I' )and (stro[1]<>'S' )then Errora(29);
   Tipi:='';
   if (stro[1]='R') then Errora(22);
   vozvr:=false;
   E;
   writeln(Fille,#9,#9'pop      bx      ;извлекаем нач знач');
   writeln(Fille,#9,#9,'sub      [@@SchPu],1');
   if  Flag_To_DownTo{to} then
    begin
     writeln(Fille,#9,#9'sub      ax,bx');
     writeln(Fille,#9,#9'cmp      ax,0');
    end
    else
    begin
     writeln(Fille,#9,#9'sub      bx,ax');
     writeln(Fille,#9,#9'cmp      bx,0');

    end;
   writeln(Fille,#9,#9'jge      @@noterr',MetkaFor1,'       ; ');
   writeln(Fille,#9,#9'jmp      endo   ; ошибка, т к д б >0');

   writeln(Fille,'@@noterr',MetkaFor1,':');

   if  Flag_To_DownTo{to} then
    writeln(Fille,#9,#9'mov      cx,ax')
   else
    writeln(Fille,#9,#9'mov      cx,bx');
   writeln(Fille,#9,#9'add      cx,1       ;когда цикл от 1 до 1 то 1раз а не 0 ');
   writeln(Fille,'@@',MetkaFor1,':');

   writeln(Fille,#9,#9'push     cx');
   writeln(Fille,#9,#9,'add      [@@SchPu],1');
   if stro<>'S29'{do} then Errora(30);
   Rezak(Ukaz,stro,ReadNot,Fil);
   if stro<>'S24'{begin} then Errora(23);
   Rezak(Ukaz,stro,ReadNot,Fil);
   while (stro<>'S25') and (stro <>'') do
    begin
     Telo; {тело  then  begin ...... end}
    end;
   if (stro = 'S25'){end}then
    begin
     Rezak(Ukaz,stro,ReadNot,Fil);
     if stro[1] <>'R' then Errora(4);
     if stro <>'R12' then Errora(26);
    end
   else Errora(24);
{---------------------------------------------------}
   if TablS[Sem_Info-1].Tip='INTEGER' then
    writeln(Fille,#9,#9'mov      ax,',helpstro)
     else
     begin
      writeln(Fille,#9,#9'xor      ax,ax');
      writeln(Fille,#9,#9'mov      al,',helpstro);
     end;
   if  Flag_To_DownTo{to} then
    writeln(Fille,#9,#9'inc      ax     ;увеличиваем перем цикла')
    else
    writeln(Fille,#9,#9'dec      ax     ;уменьшаем переменную цикла');
   if TablS[Sem_Info-1].Tip='INTEGER' then
    writeln(Fille,#9,#9'mov      ',helpstro,',ax')
    else
    writeln(Fille,#9,#9'mov      ',helpstro,',al');
   writeln(Fille,#9,#9'pop      cx           ;восстанавливаем сх');
   writeln(Fille,#9,#9,'sub      [@@SchPu],1');
   writeln(Fille,#9,#9'dec      cx');
   writeln(Fille,#9,#9'cmp      cx,0');
   writeln(Fille,#9,#9'je       @@',MetkaFor2);
   writeln(Fille,#9,#9'jmp      @@',MetkaFor1);
   writeln(Fille,'@@',MetkaFor2,':');
   writeln(Fille,';----------- for end ',MetkaFor1,'---------------');
   Rezak(Ukaz,stro,ReadNot,Fil);


  end;
 procedure Raspozn_Write;
  var
   Sem_inf,Sem_inf1:string;
   sch,cod:integer;
   MetToDec1,MetToDec2:integer;
  begin
   writeln(Fille,';----------- Write ---------------');
   Sem_inf:=stro;{ if writeln then output 13,10}
   Rezak(Ukaz,stro,ReadNot,Fil);   {читаем следующий после "write"}
   if stro[1]<>'R' then Errora(4);
   writeln(Fille,#9,#9'push     cx');
   writeln(Fille,#9,#9,'add      [@@SchPu],1');
   if stro='R12'{;} then
    begin
     if Sem_inf ='40'{writeln} then
      begin
       writeln(Fille,#9,#9'mov     ah,09');
       writeln(Fille,#9,#9'lea     dx,$ln');
       writeln(Fille,#9,#9'int     21h');
      end;
    end
    else
    begin
     if stro<>'R10'{(} then Errora(32);
     Rezak(Ukaz,stro,ReadNot,Fil);
     if (stro[1]<>'I') and (stro[1]<>'L') and (stro[1]<>'S') then Errora(31);
     writeln(Fille);
{------------------------------------------------------}
     while stro<>'R11'{)} do
      begin
       if (stro[1]<>'I') and (stro[1]<>'L') and (stro[1]<>'S')then Errora(31);
       if stro[1]='L' then
        begin
         delete(stro,1,1);
         writeln(Fille,#9,#9'mov     ah,09');
         writeln(Fille,#9,#9'lea     dx,$',stro);
         writeln(Fille,#9,#9'int     21h');
         writeln(Fille);
         Rezak(Ukaz,stro,ReadNot,Fil);
        end
       else
        begin
         Sem_inf1:=stro;
       if stro[1]='I'then
        begin
         delete(Sem_inf1,1,1);
         val(Sem_inf1,sch,cod);
         with TablS[sch-1]{имя программы - I1,а в табл симв его нет} do
                          {идент-ры начин-ся с I2,т е TablS[1]=I2}
           if (Tip = 'INTEGER')or (Tip = 'BYTE')or ( (Tip='@@arr@@') and
           ((TipLo ='INTEGER')or(TipLo ='BYTE'))) or (Sem_inf1[1]='H') then
             begin
              inc(MetToDec,3);
              MetToDec1:=MetToDec+1;
              MetToDec2:=MetToDec+2;
              writeln(Fille,#9,#9'mov      di,0Ch');
              writeln(Fille,#9,#9'mov      ss:[di],byte ptr ',#39,'$',#39);
              writeln(Fille,#9,#9'dec      di');
              E;
              if (Tip = 'INTEGER') or ((Tip='@@arr@@')and(TipLo = 'INTEGER'))
              or (Sem_inf1[1]='H')  then
               begin
                writeln(Fille,#9,#9'mov      bx,ax        ;ниже будет проверка на знак');
                writeln(Fille,#9,#9'cmp      ax,0');
               end
               else
               if (Tip = 'BYTE') or ((Tip='@@arr@@')and(TipLo = 'BYTE')) then
               begin
                writeln(Fille,#9,#9'mov      bl,al        ;ниже будет проверка на знак');
                writeln(Fille,#9,#9'cmp      al,0');
               end;

              writeln(Fille,#9,#9'jge       next',MetToDec2,'    ;>');
              if (Tip = 'INTEGER')or ((Tip='@@arr@@')and(TipLo = 'INTEGER'))
              or (Sem_inf1[1]='H') then
              writeln(Fille,#9,#9'neg      ax        ;перевод в положительн')
              else
              writeln(Fille,#9,#9'neg      al        ;перевод в положительн');
              writeln(Fille,'next',MetToDec2,':');

              writeln(Fille,#9,#9'mov      cx,10');
              writeln(Fille,'next',MetToDec,':');
              writeln(Fille,#9,#9'mov      dx,0');
              writeln(Fille,#9,#9'div      cx');
              writeln(Fille,#9,#9' or      dl,30h');
              writeln(Fille,#9,#9'mov      ss:[di],dl');
              writeln(Fille,#9,#9'dec      di');
              writeln(Fille,#9,#9'cmp      al,0');
              writeln(Fille,#9,#9'jne      next',MetToDec);
              writeln(Fille);
              if (Tip = 'INTEGER')or ((Tip='@@arr@@')and(TipLo = 'INTEGER'))
              or (Sem_inf1[1]='H') then
              writeln(Fille,#9,#9'cmp      bx,0')
               else
              writeln(Fille,#9,#9'cmp      bl,0');
              writeln(Fille,#9,#9'jge       next',MetToDec1);
              if (Tip = 'INTEGER')or ((Tip='@@arr@@')and(TipLo = 'INTEGER'))
              or (Sem_inf1[1]='H') then
              writeln(Fille,#9,#9'neg      ax')
              else
              writeln(Fille,#9,#9'neg      al');

              writeln(Fille,#9,#9'mov      ss:[di],byte ptr 2Dh  ;помещаем "-"');
              writeln(Fille,#9,#9'dec      di');
              writeln(Fille,'next',MetToDec1,':');

              writeln(Fille,#9,#9'inc      di');
              writeln(Fille,#9,#9'mov      ax,ds');
              writeln(Fille,#9,#9'push     ax           ;сохр сегм данн');
              writeln(Fille,#9,#9'mov      ax,ss');
              writeln(Fille,#9,#9'mov      ds,ax        ;сегм данн на стек');
              writeln(Fille,#9,#9'lea      dx,ss:[di]');
              writeln(Fille,#9,#9'mov      ah,09h');
              writeln(Fille,#9,#9'int      21h');

              writeln(Fille,#9,#9'pop      ax');
              writeln(Fille,#9,#9'mov      ds,ax         ;восст сегм данн');
              writeln(Fille);

             end{if integer or byte}
            else
           if (Tip ='CHAR')or ((Tip='@@arr@@') and (TipLo ='CHAR'))then
            begin
              if (Tip <>'CHAR') then
               begin
                F;
                {si - смешение в массиве}
                writeln(Fille,#9,#9'lea      bx,',name);
                writeln(Fille,#9,#9'add      bx,si        ;+смещение в массиве');
               end;
              writeln(Fille,#9,#9'mov      di,0Ch');
              writeln(Fille,#9,#9'mov      ss:[di],byte ptr ',#39,'$',#39);
              writeln(Fille,#9,#9'dec      di');

              if (Tip = 'CHAR') then
               writeln(Fille,#9,#9'mov      al,',name)
               else
                writeln(Fille,#9,#9'mov      al,byte ptr [bx]');

              writeln(Fille,#9,#9'mov      byte ptr ss:[di],al');
              writeln(Fille);
              writeln(Fille,#9,#9'mov      ax,ds');
              writeln(Fille,#9,#9'push     ax           ;сохр сегм данн');
              writeln(Fille,#9,#9'mov      ax,ss');
              writeln(Fille,#9,#9'mov      ds,ax        ;сегм данн на стек');
              writeln(Fille,#9,#9'lea      dx,ss:[di]');
              writeln(Fille,#9,#9'mov      ah,09h');
              writeln(Fille,#9,#9'int      21h');

              writeln(Fille,#9,#9'pop      ax');
              writeln(Fille,#9,#9'mov      ds,ax         ;восст сегм данн');
              writeln(Fille);
              if Tip='CHAR' then Rezak(Ukaz,stro,ReadNot,Fil);
            end
           else
           if (Tip ='STRING')or((Tip='@@arr@@') and (TipLo ='STRING')) then
            begin
              if (Tip <>'STRING') then F;
               {в si - смещение}
              writeln(Fille,#9,#9'lea      dx,',name);
              if Tip<>'STRING' then
              writeln(Fille,#9,#9'add      dx,si        ;+смещение в массиве');
              writeln(Fille,#9,#9'inc      dx       ;первый байт - длина');
              writeln(Fille,#9,#9'mov      ah,09h');
              writeln(Fille,#9,#9'int      21h');
              writeln(Fille);
              if Tip='STRING' then Rezak(Ukaz,stro,ReadNot,Fil);
            end
        end
        else
        if stro[1]='S' then
         begin
              inc(MetToDec,3);
              MetToDec1:=MetToDec+1;
              MetToDec2:=MetToDec+2;
              writeln(Fille,#9,#9'mov      di,0Ch');
              writeln(Fille,#9,#9'mov      ss:[di],byte ptr ',#39,'$',#39);
              writeln(Fille,#9,#9'dec      di');
              E;
              writeln(Fille,#9,#9'mov      cx,10');
              writeln(Fille,'next',MetToDec,':');
              writeln(Fille,#9,#9'mov      dx,0');
              writeln(Fille,#9,#9'div      cx');
              writeln(Fille,#9,#9' or      dl,30h');
              writeln(Fille,#9,#9'mov      ss:[di],dl');
              writeln(Fille,#9,#9'dec      di');
              writeln(Fille,#9,#9'cmp      al,0');
              writeln(Fille,#9,#9'jne      next',MetToDec);
              writeln(Fille);

              writeln(Fille,#9,#9'inc      di');
              writeln(Fille,#9,#9'mov      ax,ds');
              writeln(Fille,#9,#9'push     ax           ;сохр сегм данн');
              writeln(Fille,#9,#9'mov      ax,ss');
              writeln(Fille,#9,#9'mov      ds,ax        ;сегм данн на стек');
              writeln(Fille,#9,#9'lea      dx,ss:[di]');
              writeln(Fille,#9,#9'mov      ah,09h');
              writeln(Fille,#9,#9'int      21h');

              writeln(Fille,#9,#9'pop      ax');
              writeln(Fille,#9,#9'mov      ds,ax         ;восст сегм данн');
              writeln(Fille);
            {  Rezak(Ukaz,stro,ReadNot,Fil);}

         end;
        end;
       if (stro<>'R8'){,}and (stro<>'R11') then Errora(33);
       if stro = 'R8' then
        begin
         Rezak(Ukaz,stro,ReadNot,Fil);
         if stro = 'R11' then Errora(31);
        end;
      end{while};
{------------------------------------------------------}
     Rezak(Ukaz,stro,ReadNot,Fil);
     if (stro<>'R12'){;} then Errora(26);
     if Sem_inf ='40' then
      begin
       writeln(Fille,#9,#9'mov     ah,09       ;перевод строки');
       writeln(Fille,#9,#9'lea     dx,$ln');
       writeln(Fille,#9,#9'int     21h');
       writeln(Fille);
      end;

    end{if};
     writeln(Fille,#9,#9'pop     cx');
     writeln(Fille,#9,#9,'sub      [@@SchPu],1');
     writeln(Fille,';----------- End Write ---------------');
   Rezak(Ukaz,stro,ReadNot,Fil);
  end;
 procedure ClearEkr;
  begin
   writeln(Fille,';----------- Clear ---------------');
   Rezak(Ukaz,stro,ReadNot,Fil);
   if (stro<>'R12'){;} then Errora(26);
   DoCallClear:=true;
   writeln(Fille,#9,#9'call    $Clear');
   Rezak(Ukaz,stro,ReadNot,Fil);
   writeln(Fille,';----------- End Clear ---------------');
  end;

 procedure Raspozn_Read;
  var
   sch,cod:integer;
   Sem_inf:string;
   HelpStro:string;
   MetkaRead1,MetkaRead2,MetkaRead3:integer;
   MetkaRead4,MetkaRead5,MetkaRead6:integer;
   SovmTip:string;
  begin
   Tipi:='';
   inc(MetkaRead,7);
   MetkaRead1:=MetkaRead+1;
   MetkaRead2:=MetkaRead+2;
   MetkaRead3:=MetkaRead+3;
   MetkaRead4:=MetkaRead+4;
   MetkaRead5:=MetkaRead+5;
   MetkaRead6:=MetkaRead+6;
   Rezak(Ukaz,stro,ReadNot,Fil);
   if stro<>'R10'{(} then Errora(32);
   Rezak(Ukaz,stro,ReadNot,Fil);
   if (stro[1]<>'I') then Errora(31);
   Sem_inf:=stro;
   delete(Sem_inf,1,1);
   val(Sem_inf,sch,cod);
   ID.SearcElem(sch,HelpStro);{содержит имя идентиф-ра}
   SovmTip:=TablS[sch-1].Tip;{тип идентификатроа}
   writeln(Fille,';------------- начало ввода ------------');
   writeln(Fille,#9,#9'push     cx');
   writeln(Fille,#9,#9,'add      [@@SchPu],1');
   if SovmTip ='@@arr@@' then
    begin
     F;
     writeln(Fille,#9,#9'push     si');
     writeln(Fille,#9,#9,'add      [@@SchPu],1');
    end;
   {после f получили смещение}
      writeln(Fille,#9,#9'mov      si,1h');
      writeln(Fille,#9,#9'mov      bx,0h');
      writeln(Fille,'vvod',MetkaRead,':');
      writeln(Fille,#9,#9'mov	ah,01h		;функция чтения с клавиатуры и эхо');
      writeln(Fille,#9,#9'int	21h		;передача управления в BIOS');
      writeln(Fille,#9,#9'cmp	al,0dh		;сравнивание с Enter');
      writeln(Fille,#9,#9'je	short	dalshe',MetkaRead);
      writeln(Fille,#9,#9'mov	ss:[si],al');
      writeln(Fille,#9,#9'inc	si');
      writeln(Fille,#9,#9'inc	bx              ;длина вводимого');
      writeln(Fille,#9,#9'jmp	vvod',MetkaRead);
      writeln(Fille,'dalshe',MetkaRead,':');
      writeln(Fille,#9,#9'mov   ss:[si],byte ptr ',#39,'$',#39);
   {после этого по адресу ss:[si] имеем строку, кот нужно преобразовать,}
   if (SovmTip ='INTEGER')or(SovmTip ='BYTE') or (SovmTip ='@@arr@@')then
    begin
     writeln(Fille,';-----------16-е преобразование------------');
     writeln(Fille,#9,#9'mov	cx,10');
     writeln(Fille,#9,#9'lea	si,ss:[0]       ;число начин-ся с [1]');
     writeln(Fille,#9,#9';bx=длина числа');
     writeln(Fille,#9,#9'mov	dx,1h');
     writeln(Fille,#9,#9'mov	bp,0');
     writeln(Fille,'@@@',MetkaRead1,':');
     if SovmTip= 'BYTE' then
     writeln(Fille,#9,#9'mov    ax,0');
     writeln(Fille,#9,#9'mov    al,ss:[si+bx]');
     writeln(Fille,#9,#9'cmp    al,2Dh          ; это "-" ?');
     writeln(Fille,#9,#9'jne',#9,'@@@',MetkaRead4       ,';<>');
     writeln(Fille,#9,#9'cmp    bx,1h          ; это последн знак');
     writeln(Fille,#9,#9'je',#9,'@@@',MetkaRead5       ,';=');
     writeln(Fille,#9,#9'mov    ax,1');
    { if SovmTip ='@@arr@@' then    }
     writeln(Fille,#9,#9'jmp    endo');

     writeln(Fille,'@@@',MetkaRead5,':');
     writeln(Fille,#9,#9'neg	bp');
     writeln(Fille,#9,#9'jmp',#9,'@@@',MetkaRead6);

     writeln(Fille,'@@@',MetkaRead4,':');
     writeln(Fille,'');
     writeln(Fille,#9,#9'cmp	al,30h');
     writeln(Fille,#9,#9'jge',#9,'@@@',MetkaRead2       ,';>=');
     writeln(Fille,#9,#9'mov    ax,1');
     writeln(Fille,#9,#9'jmp    endo');
     writeln(Fille,'@@@',MetkaRead2,':');
     writeln(Fille,#9,#9'cmp	al,39h');
     writeln(Fille,#9,#9'jle',#9,'@@@',MetkaRead3       ,';<=');
     writeln(Fille,#9,#9'mov    ax,1');


     writeln(Fille,#9,#9'jmp    endo');
     writeln(Fille,'@@@',MetkaRead3,':');
     writeln(Fille,'');
     writeln(Fille,#9,#9'and	ax,000Fh         ');
     writeln(Fille,#9,#9'push	dx');
     writeln(Fille,#9,#9'mul	dx');
     writeln(Fille,#9,#9'pop	dx');
     writeln(Fille,#9,#9'add	bp,ax           ;результат 16-й');
     writeln(Fille,#9,#9'mov	ax,dx');
     writeln(Fille,#9,#9'mul	cx');
     writeln(Fille,#9,#9'mov	dx,ax');
     writeln(Fille,#9,#9'dec	bx');
     writeln(Fille,#9,#9'jnz     @@@',MetkaRead1);
     writeln(Fille,';-----------конец 16-го преобразования------------');
     writeln(Fille,'@@@',MetkaRead6,':');
     if SovmTip ='@@arr@@' then
      begin
       writeln(Fille,#9,#9'pop     si   ;вынимаем смещение');
       writeln(Fille,#9,#9,'sub      [@@SchPu],1');
       writeln(Fille,#9,#9'lea     bx,',HelpStro,'    ;куда выводить');
       if TablS[sch-1].TipLo = 'INTEGER' then
       writeln(Fille,#9,#9'mov     [bx+si],bp    ;занесение результата')
       else
       begin
        writeln(Fille,#9,#9'mov     ax,bp');
        writeln(Fille,#9,#9'mov     [bx+si],al    ;занесение результата');
       end;

      end;

     if SovmTip='INTEGER' then
     writeln(Fille,#9,#9'mov',#9,HelpStro,',bp    ;занесение результата')
     else
     if SovmTip='BYTE' then
      begin
       writeln(Fille,#9,#9'mov     ax,bp');
       writeln(Fille,#9,#9'mov     ',HelpStro,',al    ;занесение результата')
      end;
    end
   else
    if (SovmTip ='CHAR') then
     begin
      writeln(Fille,#9,#9'cmp	bx,1        ;введден один символ ?');
      writeln(Fille,#9,#9'je	dalshe',MetkaRead1);
      writeln(Fille,#9,#9'mov    ax,1');
      {writeln(Fille,#9,#9'pop    cx');}
      writeln(Fille,#9,#9'jmp    endo');
      writeln(Fille,'dalshe',MetkaRead1,':');
      writeln(Fille,#9,#9'mov    si,1h');
      writeln(Fille,#9,#9'mov    al,byte ptr ss:[si]');
      writeln(Fille,#9,#9'mov',#9,HelpStro,',al    ;занесение результата');
     end
   else
    if (SovmTip ='STRING') then
     begin

              writeln(Fille,#9,#9'mov      ax,ds');
              writeln(Fille,#9,#9'push     ax           ;сохр сегм данн');
              writeln(Fille,#9,#9'mov      ax,ss');
              writeln(Fille,#9,#9'mov      ds,ax        ;сегм данн на стек');


      writeln(Fille,#9,#9'mov     si,01h');
      writeln(Fille,#9,#9'lea     di,',HelpStro,'      ;адрес куда');
      writeln(Fille,#9,#9'mov     es:[di],bx           ;первый байт строки - длина');
      writeln(Fille,#9,#9'inc     di');
      writeln(Fille,#9,#9'mov     cx,bx');
      writeln(Fille,#9,#9'inc     cx      ;длина передаваемой строки +"$"');
      writeln(Fille,#9,#9'rep     movsb');

             writeln(Fille,#9,#9'pop      ax');
             writeln(Fille,#9,#9'mov      ds,ax         ;восст сегм данн');
              writeln(Fille);


     end;

   writeln(Fille,#9,#9'mov     ah,09           ;перевод строки');
   writeln(Fille,#9,#9'lea     dx,$ln');
   writeln(Fille,#9,#9'int     21h');

   writeln(Fille,#9,#9'pop     cx');
   writeln(Fille,#9,#9,'sub      [@@SchPu],1');
   writeln(Fille,';------------- конец ввода ------------');

   if SovmTip<>'@@arr@@'then Rezak(Ukaz,stro,ReadNot,Fil);
   if stro<>'R11'{)} then Errora(33);
   Rezak(Ukaz,stro,ReadNot,Fil);
   if stro<>'R12'{;} then Errora(26);
   Rezak(Ukaz,stro,ReadNot,Fil);

  end;

 procedure Raspozn_Del;
  var
   FromStr:string;
   FromNumPos:integer;
   HowMany,sch,cod:integer;
   MetkaDel1,MetkaDel2,MetkaDel3:integer;
  begin
   DoCallDel:=true;
   inc(MetkaDel,4);
   MetkaDel1:=MetkaDel+1;
   MetkaDel2:=MetkaDel+2;
   MetkaDel3:=MetkaDel+3;
   Rezak(Ukaz,stro,ReadNot,Fil);
   if stro<>'R10'{(} then Errora(32);
   Rezak(Ukaz,stro,ReadNot,Fil);
   if stro[1]<>'I' then Errora(8);
   FromStr:=stro;{строка из которой удаляем}
   delete(FromStr,1,1);
   val(FromStr,sch,cod);
   writeln(Fille,';---------------- удаление -------------------');
   writeln(Fille,#9,#9'push    cx');
   writeln(Fille,#9,#9,'add      [@@SchPu],1');
   if (TablS[sch-1].Tip<>'STRING') and ((TablS[sch-1].Tip='@@arr@@')and
   (TablS[sch-1].TipLo<>'STRING')) then Errora(37);
   ID.SearcElem(sch,FromStr);

   if ((TablS[sch-1].Tip='@@arr@@')and (TablS[sch-1].TipLo='STRING'))then
    begin
     F;
     { в si - смещение}
     writeln(Fille,#9,#9'lea     bx,',FromStr);{откуда}
     writeln(Fille,#9,#9'add     si,bx');
    end
    else
    writeln(Fille,#9,#9'lea    si,',FromStr);{откуда}
    writeln(Fille,#9,#9'xor     ax,ax');
   writeln(Fille,#9,#9'mov     al,byte ptr [si]');
   writeln(Fille,#9,#9'cmp     ax,0');
   writeln(Fille,#9,#9'jg     @Dela',MetkaDel3,'        ;>');
   writeln(Fille,#9,#9'mov     ax,1');
   writeln(Fille,#9,#9'jmp     endo');


   writeln(Fille,'@Dela',MetkaDel3,':');


   writeln(Fille,#9,#9'push     si');
   writeln(Fille,#9,#9,'add      [@@SchPu],1');
   if TablS[sch-1].Tip='STRING'then Rezak(Ukaz,stro,ReadNot,Fil);
   if stro<>'R8'{,} then Errora(40);
   Rezak(Ukaz,stro,ReadNot,Fil);
   if (stro[1]<>'I')and(stro[1]<>'H') then Errora(8);
   E;
   {в ах номер, с какой литеры удалять}
   writeln(Fille,#9,#9'push     ax');
   writeln(Fille,#9,#9,'add      [@@SchPu],1');
   if stro<>'R8'{,} then Errora(40);
   Rezak(Ukaz,stro,ReadNot,Fil);
   if (stro[1]<>'I')and (stro[1]<>'H') then Errora(8);
   E;

   writeln(Fille,#9,#9'mov     cx,ax      ;сколько удалять');
   writeln(Fille,#9,#9'pop     ax         ;c какого номера');
   writeln(Fille,#9,#9,'sub      [@@SchPu],1');
   writeln(Fille,#9,#9'pop     bx         ;где');
   writeln(Fille,#9,#9,'sub      [@@SchPu],1');
   writeln(Fille,#9,#9'cmp     ax,0');
   writeln(Fille,#9,#9'jge     @Dela',MetkaDel1,'        ;>=');
  { writeln(Fille,#9,#9'pop     cx');}
   writeln(Fille,#9,#9'mov     ax,1');
   writeln(Fille,#9,#9'jmp     endo');


   writeln(Fille,'@Dela',MetkaDel1,':');
   writeln(Fille,#9,#9'mov     bp,cx');
   writeln(Fille,#9,#9'add     bp,ax   ;установка пользователя');
   writeln(Fille,#9,#9'sub     bp,1    ;1-я буква в строке - индекс 1,а не 0');
   writeln(Fille,#9,#9'xor     dx,dx');
   writeln(Fille,#9,#9'mov     dl,byte ptr [bx] ;истинная длина строки');
   writeln(Fille,#9,#9'sub     dx,bp');
   writeln(Fille,#9,#9'cmp     dx,0');
   writeln(Fille,#9,#9'jge     @Dela',MetkaDel2,'        ;>=');
   writeln(Fille,#9,#9'mov     ax,1');
   writeln(Fille,#9,#9'jmp     endo');

   writeln(Fille,'@Dela',MetkaDel2,':');


   writeln(Fille,#9,#9'call    $Del       ;процедура удаления');
   writeln(Fille,#9,#9'pop     cx');
   writeln(Fille,#9,#9,'sub      [@@SchPu],1');
   writeln(Fille,';---------------- конец удаления -------------------');
   if stro<>'R11'{)} then Errora(33);
   Rezak(Ukaz,stro,ReadNot,Fil);
   if stro<>'R12'{;} then Errora(26);
   Rezak(Ukaz,stro,ReadNot,Fil);
  end;
 procedure Raspozn_Copy;
  var
   FromStr,ToStr:string;
   FromNumPos:integer;
   HowMany,sch,cod:integer;
   MetkaCopy1,MetkaCopy2,MetkaCopy3:integer;
  begin
   DoCallCopy:=true;
   inc(MetkaCopy,4);
   MetkaCopy1:=MetkaCopy+1;
   MetkaCopy2:=MetkaCopy+2;
   MetkaCopy3:=MetkaCopy+3;
   Rezak(Ukaz,stro,ReadNot,Fil);
   if stro<>'R10'{(} then Errora(32);
   Rezak(Ukaz,stro,ReadNot,Fil);
   if stro[1]<>'I' then Errora(8);
{------------ работа с "куда"------------------------------- }
   ToStr:=stro;
   delete(ToStr,1,1);
   val(ToStr,sch,cod);
   writeln(Fille,';---------------- копи -------------------');
   writeln(Fille,#9,#9'push    cx');
   writeln(Fille,#9,#9,'add      [@@SchPu],1');
   if (TablS[sch-1].Tip<>'STRING') and ((TablS[sch-1].Tip='@@arr@@')and
   (TablS[sch-1].TipLo<>'STRING')) then Errora(37);
   ID.SearcElem(sch,ToStr);

   if ((TablS[sch-1].Tip='@@arr@@')and (TablS[sch-1].TipLo='STRING'))then
    begin
     F;
     { в si - смещение}
     writeln(Fille,#9,#9'lea     bx,',ToStr);{куда}
     writeln(Fille,#9,#9'add     si,bx');
    end
    else
    writeln(Fille,#9,#9'lea    si,',ToStr);{куда}

   writeln(Fille,#9,#9'push     si        ;сохраняем куда');
   writeln(Fille,#9,#9,'add      [@@SchPu],1');
{------------ конец работы с "куда"------------------------------- }
   if TablS[sch-1].Tip='STRING'then Rezak(Ukaz,stro,ReadNot,Fil);
   if stro<>'R8'{,} then Errora(40);
   Rezak(Ukaz,stro,ReadNot,Fil);
{------------ работа с "откуда"------------------------------- }
   if stro[1]<>'I' then Errora(8);
   FromStr:=stro;
   delete(FromStr,1,1);
   val(FromStr,sch,cod);
   if (TablS[sch-1].Tip<>'STRING') and ((TablS[sch-1].Tip='@@arr@@')and
   (TablS[sch-1].TipLo<>'STRING')) then Errora(37);
   ID.SearcElem(sch,FromStr);

   if ((TablS[sch-1].Tip='@@arr@@')and (TablS[sch-1].TipLo='STRING'))then
    begin
     F;
     { в si - смещение}
     writeln(Fille,#9,#9'lea     bx,',FromStr);{откуда}
     writeln(Fille,#9,#9'add     si,bx');
    end
    else
    writeln(Fille,#9,#9'lea    si,',FromStr);{откуда}
    writeln(Fille,#9,#9'xor     ax,ax');
   writeln(Fille,#9,#9'mov     al,byte ptr [si]');
   writeln(Fille,#9,#9'cmp     ax,0');
   writeln(Fille,#9,#9'jg     @Copya',MetkaCopy3,'        ;>');
   {writeln(Fille,#9,#9'pop     cx');   }
   writeln(Fille,#9,#9'mov     ax,1');
   writeln(Fille,#9,#9'jmp     endo');


   writeln(Fille,'@Copya',MetkaCopy3,':');


   writeln(Fille,#9,#9'push     si        ;сохраняем куда');
   writeln(Fille,#9,#9,'add      [@@SchPu],1');
{---------------------конец работы с "откуда"-------------------}
   if TablS[sch-1].Tip='STRING'then Rezak(Ukaz,stro,ReadNot,Fil);
   if stro<>'R8'{,} then Errora(40);
   Rezak(Ukaz,stro,ReadNot,Fil);


   if (stro[1]<>'I')and(stro[1]<>'H') then Errora(8);
   E;
   {в ах номер, с какой литеры удалять}
   writeln(Fille,#9,#9'push     ax');
   writeln(Fille,#9,#9,'add      [@@SchPu],1');
   if stro<>'R8'{,} then Errora(40);
   Rezak(Ukaz,stro,ReadNot,Fil);
   if (stro[1]<>'I')and (stro[1]<>'H') then Errora(8);
   E;

   writeln(Fille,#9,#9'mov     cx,ax      ;сколько ');
   writeln(Fille,#9,#9'pop     ax         ;c какого номера');
   writeln(Fille,#9,#9,'sub      [@@SchPu],1');
   writeln(Fille,#9,#9'pop     si         ;откуда');
   writeln(Fille,#9,#9,'sub      [@@SchPu],1');
   writeln(Fille,#9,#9'pop     di         ;куда');
   writeln(Fille,#9,#9,'sub      [@@SchPu],1');

   writeln(Fille,#9,#9'cmp     ax,0');
   writeln(Fille,#9,#9'jge     @Copya',MetkaCopy1,'        ;>=');
   writeln(Fille,#9,#9'mov     ax,1');
   writeln(Fille,#9,#9'jmp     endo');


   writeln(Fille,'@Copya',MetkaCopy1,':');
   writeln(Fille,#9,#9'mov     bp,cx');
   writeln(Fille,#9,#9'add     bp,ax   ;установка пользователя');
   writeln(Fille,#9,#9'sub     bp,1    ;1-я буква в строке имеет индекс 1,а не 0');
   writeln(Fille,#9,#9'xor     dx,dx');
   writeln(Fille,#9,#9'mov     dl,byte ptr [si] ;истинная длина строки');
   writeln(Fille,#9,#9'sub     dx,bp');
   writeln(Fille,#9,#9'cmp     dx,0');
   writeln(Fille,#9,#9'jge     @Copya',MetkaCopy2,'        ;>=');
   writeln(Fille,#9,#9'mov     ax,1');
   writeln(Fille,#9,#9'jmp     endo');

   writeln(Fille,'@Copya',MetkaCopy2,':');


   writeln(Fille,#9,#9'call    $Copy       ;процедура удаления');
   writeln(Fille,#9,#9'pop     cx');
   writeln(Fille,#9,#9,'sub      [@@SchPu],1');
   writeln(Fille,';---------------- конец копи -------------------');
   if stro<>'R11'{)} then Errora(33);
   Rezak(Ukaz,stro,ReadNot,Fil);
   if stro<>'R12'{;} then Errora(26);
   Rezak(Ukaz,stro,ReadNot,Fil);
  end;
 procedure Raspozn_Insert;
  var
   FromStr,ToStr:string;
   FromNumPos:integer;
   sch,cod:integer;
   MetkaInsert1,MetkaInsert2,MetkaInsert3:integer;
  begin
   DoCallIns:=true;
   inc(MetkaInsert,4);
   MetkaInsert1:=MetkaInsert+1;
   MetkaInsert2:=MetkaInsert+2;
    MetkaInsert3:=MetkaInsert+3;
   Rezak(Ukaz,stro,ReadNot,Fil);
   if stro<>'R10'{(} then Errora(32);
   Rezak(Ukaz,stro,ReadNot,Fil);
   if stro[1]<>'I' then Errora(8);
{------------ работа с "откуда"------------------------------- }
   FromStr:=stro;
   delete(FromStr,1,1);
   val(FromStr,sch,cod);
   writeln(Fille,';---------------- вставка -------------------');
   writeln(Fille,#9,#9'push    cx');
   writeln(Fille,#9,#9,'add      [@@SchPu],1');
   if (TablS[sch-1].Tip<>'STRING') and ((TablS[sch-1].Tip='@@arr@@')and
   (TablS[sch-1].TipLo<>'STRING')) then Errora(37);
   ID.SearcElem(sch,FromStr);

   if ((TablS[sch-1].Tip='@@arr@@')and (TablS[sch-1].TipLo='STRING'))then
    begin
     F;
     { в si - смещение}
     writeln(Fille,#9,#9'lea     bx,',FromStr);{откуда}
     writeln(Fille,#9,#9'add     si,bx');
    end
    else
    writeln(Fille,#9,#9'lea    si,',FromStr);{откуда}

   writeln(Fille,#9,#9'push     si        ;сохраняем откуда');
   writeln(Fille,#9,#9,'add      [@@SchPu],1');
{------------ конец работы с "откуда"------------------------------- }
   if TablS[sch-1].Tip='STRING'then Rezak(Ukaz,stro,ReadNot,Fil);
   if stro<>'R8'{,} then Errora(40);
   Rezak(Ukaz,stro,ReadNot,Fil);
{------------ работа с "куда"------------------------------- }
   if stro[1]<>'I' then Errora(8);
   ToStr:=stro;
   delete(ToStr,1,1);
   val(ToStr,sch,cod);
   if (TablS[sch-1].Tip<>'STRING') and ((TablS[sch-1].Tip='@@arr@@')and
   (TablS[sch-1].TipLo<>'STRING')) then Errora(37);
   ID.SearcElem(sch,ToStr);

   if ((TablS[sch-1].Tip='@@arr@@')and (TablS[sch-1].TipLo='STRING'))then
    begin
     F;
     { в si - смещение}
     writeln(Fille,#9,#9'lea     bx,',ToStr);{куда}
     writeln(Fille,#9,#9'add     si,bx');
    end
    else
    writeln(Fille,#9,#9'lea    si,',ToStr);{куда}

   writeln(Fille,#9,#9'push     si        ;сохраняем куда');
   writeln(Fille,#9,#9,'add      [@@SchPu],1');
{---------------------конец работы с "куда"-------------------}
   if TablS[sch-1].Tip='STRING'then Rezak(Ukaz,stro,ReadNot,Fil);
   if stro<>'R8'{,} then Errora(40);
   Rezak(Ukaz,stro,ReadNot,Fil);


   if (stro[1]<>'I')and(stro[1]<>'H') then Errora(8);
   E;
   {в ах номер, с какого вставлять}

   writeln(Fille,#9,#9'pop     di         ;куда');
   writeln(Fille,#9,#9,'sub      [@@SchPu],1');
   writeln(Fille,#9,#9'pop     si         ;откуда, т е что');
   writeln(Fille,#9,#9,'sub      [@@SchPu],1');
   writeln(Fille,#9,#9'xor     bx,bx');
   writeln(Fille,#9,#9'xor     dx,dx');
   writeln(Fille,#9,#9'mov     bl,byte ptr [di]');
   writeln(Fille,#9,#9'push    bx');
   writeln(Fille,#9,#9'add     [@@SchPu],1');
   writeln(Fille,#9,#9'mov     dl,byte ptr [si]');
   writeln(Fille,#9,#9'add     bx,dx     ;длина, кот получится после Ins ');
   writeln(Fille,#9,#9'cmp     bx,254    ;тк размер + $ - два байта');
   writeln(Fille,#9,#9'jle     @Insa',MetkaInsert1,'        ;<=');
   writeln(Fille,#9,#9'mov     ax,1');
   writeln(Fille,#9,#9'jmp     endo');


   writeln(Fille,'@Insa',MetkaInsert1,':');
   writeln(Fille,#9,#9'cmp     ax,0');
   writeln(Fille,#9,#9'jg     @Insa',MetkaInsert2,'        ;>');
   writeln(Fille,#9,#9'mov     ax,1');
   writeln(Fille,#9,#9'jmp     endo');

   writeln(Fille,'@Insa',MetkaInsert2,':');
   writeln(Fille,#9,#9'pop     cx');
   writeln(Fille,#9,#9'sub     [@@SchPu],1');
   writeln(Fille,#9,#9'add     cx,1');
   writeln(Fille,#9,#9'cmp     ax,cx');
   writeln(Fille,#9,#9'jle     @Insa',MetkaInsert3,'        ;<=');
   writeln(Fille,#9,#9'mov     ax,1');
   writeln(Fille,#9,#9'jmp     endo');

   writeln(Fille,'@Insa',MetkaInsert3,':');



   writeln(Fille,#9,#9'call    $Ins       ;процедура удаления');
   writeln(Fille,#9,#9'pop     cx');
   writeln(Fille,#9,#9,'sub      [@@SchPu],1');
   writeln(Fille,';---------------- конец вставки -------------------');
   if stro<>'R11'{)} then Errora(33);
   Rezak(Ukaz,stro,ReadNot,Fil);
   if stro<>'R12'{;} then Errora(26);
   Rezak(Ukaz,stro,ReadNot,Fil);
  end;
 procedure Raspozn_Press;
  begin
   DoCallPress:=true;
   Rezak(Ukaz,stro,ReadNot,Fil);
   if stro<>'R12'{;} then Errora(26);
   Rezak(Ukaz,stro,ReadNot,Fil);
   writeln(Fille,#9,#9,'call     $Press')
  end;
 procedure Telo;
  var
   info,cod:integer;
   helpstro:string[3];
  begin
     if (stro[1]<>'S') and (stro[1]<>'I') then Errora(17);
     if stro[1]='I' then
      begin
       helpstro:= copy(stro,2,length(stro)-1);
       val(helpstro,info,cod);
       with TablS[info-1] do
        begin
         if Tip='CHAR' then
          begin
           Tipi:='CHAR';
           Prisvaivanie_Char
          end
          else
         if Tip='STRING' then
          begin
           Tipi:='STRING';
           Prisvaivanie_Char;
          end

         else
         if (Tip='INTEGER') then
          begin
           Tipi:='INTEGER';
           Prisvaivanie_Int_Byte;
          end
         else
         if (Tip='BYTE') then
          begin
           Tipi:='BYTE';
           Prisvaivanie_Int_Byte;
          end
         else
         if (Tip='@@arr@@') then
          begin
           Tipi:='@@arr@@';
           TipiLo:=TipLo;
           if (TipLo ='INTEGER')or (TipLo ='BYTE') then
            Prisvaivanie_Int_Byte;
           if (TipLo ='CHAR') or (TipLo ='STRING') then Prisvaivanie_Char;
          end
        end;
       Tipi:='';
      end
     else
     if stro[1]='S' then
      begin
       delete(stro,1,1);
       val(stro,info,cod);
       case info of

        15    : Raspozn_Del;
        16    : Raspozn_Insert;
        17    : Raspozn_Copy;
        25    : begin
                 Rezak(Ukaz,stro,ReadNot,Fil);
                 if stro[1]<>'R' then Errora(4);
                 if stro<>'R9' then Errora(3);
                end;
        26    : Raspozn_FOR;
        30    : Raspozn_IF;
        39,40 : Raspozn_Write;
        41    : Raspozn_Read;
        50    : Raspozn_Press;
        51    : ClearEkr;
       else
        Errora(22);
       end
      end;
  end;
 procedure ToBuildAsmData;
  var
   info,cod:integer;
  begin
   {$I-}
   Assign(Fille,'EndFil.asm');  {открываем}
   Rewrite(Fille);
   if IOResult<>0 then Errora(13);
   {$I+}
   BeginExe; {построение формата ехе и запись данных from TablS to EndFil.asm}
   Rezak(Ukaz,stro,ReadNot,Fil);{вырезаем =>-ий элемент после begin}
   if stro='' then Errora(25);
   while stro<>'R9' do
    begin
     Telo;
    end;

   EndExe; {дописываем концовку файла}
   close(Fille);

  end;
 procedure SintaxAnalis;
  begin
   {$I-}
   Assign(Fil,'String.txt');
   Reset(Fil);
   if IOResult<>0 then Errora(13);
   {$I+}

   TabSimb; {обрабатывает String.txt до begin и строит таблицу символов}

   ToBuildAsmData; {переписывает табл симв в файл EndFil.asm и продолжает
                    обрабатывать String.txt}

   close(fil);
  end;
 BEGIN
  Initial;
  Write('Введите имя файла для компиляции : ');
  ReadLn(WorkString);
  Assign(Var_File,WorkString);
  {$I-}
  Reset(Var_File);
  if IOResult<>0 then Errora(13);
  {$I+}
  writeln('Лексический анализ !');
  LexicAnalis;
  writeln('Готово !');
  readkey;
  writeln('Синтаксический анализ !');
  SintaxAnalis;
  writeln('Готово !');
 {PrntStks;}
  DisposeStack(ID.StackDat);
  DisposeStack(Chisla.StackDat);
  DisposeStack(Literal.StackDat);
  writeln('Компиляция завершена успешно !!! Смотри файл endfil.asm !!!');
  readkey;
 END  .










